今天,這個單元主要是練習並熟悉關於陣列的一些方法,如處理資料、篩選資料等等。
而題目也分為8題
此處為題目會用到的資料
const inventors = [
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];
const people = ['Beck, Glenn', 'Becker, Carl', 'Beckett, Samuel', 'Beddoes, Mick', 'Beecher, Henry', 'Beethoven, Ludwig', 'Begin, Menachem', 'Belloc, Hilaire', 'Bellow, Saul', 'Benchley, Robert', 'Benenson, Peter', 'Ben-Gurion, David', 'Benjamin, Walter', 'Benn, Tony', 'Bennington, Chester', 'Benson, Leana', 'Bent, Silas', 'Bentsen, Lloyd', 'Berger, Ric', 'Bergman, Ingmar', 'Berio, Luciano', 'Berle, Milton', 'Berlin, Irving', 'Berne, Eric', 'Bernhard, Sandra', 'Berra, Yogi', 'Berry, Halle', 'Berry, Wendell', 'Bethea, Erin', 'Bevan, Aneurin', 'Bevel, Ken', 'Biden, Joseph', 'Bierce, Ambrose', 'Biko, Steve', 'Billings, Josh', 'Biondo, Frank', 'Birrell, Augustine', 'Black, Elk', 'Blair, Robert', 'Blair, Tony', 'Blake, William'];
filter也就是過濾資料,他會一個個去做過濾的動作
,給予一組陣列,
return(可省略)一個以條件過濾的結果,返回一個新的陣列,但並不影響原本的陣列
console.table(),也就是資料以table呈現。
Array.prototype.filter()
1. Filter the list of inventors for those who were born in the 1500's
let year = inventors.filter((inventor) => inventor.year >= 1500 && inventor.year < 1600);
console.table(year);
map與foreach最大差別,是否回回傳一個新的陣列
foreach用的時機,當我們想對陣列內的每一個內容做處理
map用的時機,當我們想對陣列內的每一個內容做處理,並產生一個新的陣列
Array.prototype.map()
2. Give us an array of the inventors first and last names
map寫法
let names = inventors.map(inventor => inventor.first + ' ' + inventor.last);
console.log(names);
forEach寫法(錯誤)
let foreachNames = inventors.forEach(inventor => inventor.first + ' ' + inventor.last);
console.log(foreachNames); // undefined
forEach寫法正確寫法
創建一個新的陣列
let arr = [];
把處理完的資料一個個推進arr裡面
inventors.forEach(inventor =>arr.push(inventor.first + ' ' + inventor.last));
console.log(arr);
sort通常需要放兩個參數
,去兩兩做比較,預設是用字串比較
Array.prototype.sort()
3. Sort the inventors by birthdate, oldest to youngest
一般來說,直接sort,都是針對純值或是字串,會預設由小到大
let arr = [1, 8, 5, 6, 7, 2];
let arr2 = ['a', 'c', 'd', 'b'];
arr.sort();
arr2.sort();
console.log(arr); // [1, 2, 5, 6, 7, 8]
console.log(arr2); //["a", "b", "c", "d"]
<0[a,b] / =0(不變) / >0[b,a]
如果減去<0,前面的擺前面,如果等於0,不動,如果>0,後面擺前面
let ages = inventors.sort((a, b) => a.year - b.year)
console.table(ages);
第一個參數為處理,函數中又有兩個參數(sum為總和,inventor為inventors的各筆資料)
第二個參數為初始值(0)
Array.prototype.reduce()
4. How many years did all the inventors live all together?
let sum = inventors.reduce((sum, inventor) => {
return sum + (inventor.passed - inventor.year)
}, 0)
// 當跑第一次sum=0 , inventor={first: 'Albert',last: 'Einstein',year: 1879, passed: 1955}
// 第二次sum=76 , {first: 'Isaac',last: 'Newton',year: 1643,passed: 1727}...
console.log(sum); // 861
用foreach操作
let sum = 0;
inventors.forEach((inventor) => {
sum += (inventor.passed - inventor.year)
});
console.log(sum); // 861
5. Sort the inventors by years lived
新增一格年齡,以示歲數排列清楚
inventors.forEach((inventor) => {
inventor.yearsOld = inventor.passed - inventor.year;
});
年齡做相減排列由大到小
let ages = inventors.sort((b, a) => {
return (a.passed - a.year) - (b.passed - b.year)
});
console.table(ages);
由於資料是以querySelectorAll獲取,故資料為偽陣列,所以不可用map,而在此我們需要利用Array.from將偽陣列轉為真實的陣列
,在用map遍歷並處理完資料後,取資料的title,並以includes方法去找含有'de'的資料
(includes() 方法會判斷陣列是否包含特定的元素,並以此來回傳 true 或 false)
6. create a list of Boulevards in Paris that contain 'de' anywhere in the name
https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris
// 獲取全部資料(偽陣列(不可用map))
let six = document.querySelectorAll('.mw-category-group li a');
console.log(six); //NodeList(38) [a, a, a, a, a, a,....
// 利用Array.from轉為真實陣列
let arraySix = Array.from(six);
console.log(arraySix); // (38) [a, a, a, a, a, a, a, a, a, a, ...
// 利用map遍歷並獲取data(a標籤下)的title,然後再利用filter過濾title中,是否含有'de'
let de = arraySix.map(data => data.title).filter(dataTitle => dataTitle.includes('de'));
console.log(de); // (12) ["Boulevard de l'Amiral-Bruix", "Boulevard des Capucines", "Boulevard de ...]
此題,我們利用split()隔開元素,他會回傳成陣列形式
,並可個別取名,將名字分為a,b兩個陣列取出來比較
也可寫成a.split(' ');,預設以,隔開
,而split(', ')中的(, )是參考我們要切的內容
。
如果不加上[0]整個名字都會去比較,第一個字母相同的話就會去比較第二個字母。
7. sort Exercise
Sort the people alphabetically by last name
let peopleNames = people.sort((a, b) => {
let [aFirstName, aLastName] = a.split(', ');
let [bFirstName, bLastName] = b.split(', ');
// 加上[0](只會比較字首),如果a字母大於b字母(D>B)則[b,a],為0則不變,小於則[a,b]
// return aLastName > bLastName ? 1 : bLastName> aLastName ? -1 : 0
return aLastName[0] > bLastName[0] ?1 :bLastName[0] > aLastName[0] ?-1 :0;});
console.table(peopleNames);
此題,我們將初始值設為一個空物件,為了將計算後的每個實體都放進去,並做判斷,譬如如果物件中沒有'car',那麼就將'car'加至物件中,並賦予屬性值為1,如果再拿到一個'car',就直接將其屬性值+1。
8. Reduce Exercise
Sum up the instances of each of these
要計算的資料
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck', 'pogostick'];
// 計算總數
let value = 0;
// 初始值為空物件
let total = data.reduce((obj, item) => {
// 如果物件中沒有這個屬性,就創建一個並給予屬性值為1
if (!obj[item]) {
obj[item] = 1;
// 每一次屬性值+1時都會+1
value++; // 計算出總數
}
// 如果已經有某屬性,也就是重複出現就+1
else {
obj[item] += 1;
// 每一次屬性值+1時都會+1
value++;
}
console.log(obj); // {car: 1} => {car: 2} => {car: 2, truck: 1}...
console.log(obj[item]); // 當前屬性值 1=>2=>1...
return obj;
}, {});
console.table(total); // {car: 5, truck: 3, bike: 2, walk: 2, van: 2}
console.log(value); //14